#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h> 
#include<unistd.h>
#include<stdlib.h>

void childRun()
{
    int cnt = 5;
    int* p = NULL;
    while(cnt)
    {
        printf("I am child, pid: %d, ppid: %d, cnt: %d\n", getpid(), getppid(), cnt);
        sleep(1);
        cnt--;
        //测试进程异常退出后，通过wait或waitpid函数获取其退出信号：
        if(cnt == 2)
        {
            //出现异常Linux系统会直接将子进程kill掉：
            *p = 0;
        }
    }
}
int main()
{
    printf("I am father, pid: %d, ppid: %d\n", getpid(), getppid());

    pid_t id = fork();
    if(id == 0)
    {
        //child:
        childRun();
        printf("child quit...\n");
        exit(123);
    }
    //father:
    sleep(8);
    //status本质上是一个输出型参数，这个可以参考scanf("%d", &a);
    int status = 0; 

    //wait 和 waitpid函数的使用:
    //pid_t wid = wait(NULL);
    pid_t wid =  waitpid(id, &status, 0);
    if(wid > 0)
    {
        printf("wait success, wid: %d\n", wid);
    }
    else 
    {
        printf("wait failed...wid: %d\n", wid);    
    }
    sleep(5);
    //通过位运算获取进程的退出码和退出信号：
    //printf("father quit..., child exit_code: %d, child exit_signal: %d\n",(status>>8)&0xFF, status & 0x7F);

    //通过宏判断进程是否正常退出，如果是正常退出的，通过宏获取它的退出码：
    if(WIFEXITED(status))
    {
        printf("Normal exit, exit_code-> %d\n", WEXITSTATUS(status));
    }
    else 
    {
        printf("Abnormal exit, exit_signal-> %d\n", status & 0x7f);
    }
    
    return 0;
}
